use rsa::{RsaPrivateKey, RsaPublicKey};
use rsa::pkcs8::{DecodePrivateKey, DecodePublicKey, spki::Error as SpkiError};
use sha2::{Sha256, Digest};
use libp2p::{identity::Keypair, PeerId};
use std::fs::read_to_string;
use std::fmt;

#[derive(Debug)]
pub enum CryptoError {
    IoError(std::io::Error),
    Pkcs8Error(rsa::pkcs8::Error),
    SignError(String),
    VerifyFailed,
}

impl From<std::io::Error> for CryptoError {
    fn from(err: std::io::Error) -> Self {
        CryptoError::IoError(err)
    }
}

impl From<rsa::pkcs8::Error> for CryptoError {
    fn from(err: rsa::pkcs8::Error) -> Self {
        CryptoError::Pkcs8Error(err)
    }
}

impl From<SpkiError> for CryptoError {
    fn from(err: SpkiError) -> Self {
        CryptoError::Pkcs8Error(rsa::pkcs8::Error::from(err))
    }
}

impl fmt::Display for CryptoError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            CryptoError::IoError(e) => write!(f, "IO错误: {}", e),
            CryptoError::Pkcs8Error(e) => write!(f, "PKCS8错误: {}", e),
            CryptoError::SignError(e) => write!(f, "签名错误: {}", e),
            CryptoError::VerifyFailed => write!(f, "验证失败"),
        }
    }
}

impl std::error::Error for CryptoError {
    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
        match self {
            CryptoError::IoError(e) => Some(e),
            CryptoError::Pkcs8Error(e) => Some(e),
            CryptoError::SignError(_) => None,
            CryptoError::VerifyFailed => None,
        }
    }
}

/// 用根私钥签名Peer ID，生成凭证（仅用于信任节点生成凭证）
pub fn sign_peer_id(
    root_private_key_path: &str,
    peer_id: &PeerId
) -> Result<Vec<u8>, CryptoError> {
    // 读取根私钥
    let root_private_pem = read_to_string(root_private_key_path)?;
    let root_private_key = RsaPrivateKey::from_pkcs8_pem(&root_private_pem)?;

    // 哈希Peer ID
    let peer_id_string = peer_id.to_string();
    let peer_id_bytes = peer_id_string.as_bytes();
    let peer_id_hash = Sha256::digest(peer_id_bytes);

    // 简单RSA签名（不使用复杂的填充方案）
    let signature = root_private_key.sign(
        rsa::Pkcs1v15Sign::new_unprefixed(),
        &peer_id_hash
    ).map_err(|e| CryptoError::SignError(e.to_string()))?;

    Ok(signature)
}

/// 用根公钥验证凭证有效性（所有私有节点均需实现）
pub fn verify_signature(
    root_public_key_path: &str,
    peer_id: &PeerId,
    signature: &[u8]
) -> Result<(), CryptoError> {
    // 读取根公钥
    let root_public_pem = read_to_string(root_public_key_path)?;
    let root_public_key = RsaPublicKey::from_public_key_pem(&root_public_pem)?;

    // 哈希Peer ID（与签名时一致）
    let peer_id_string = peer_id.to_string();
    let peer_id_bytes = peer_id_string.as_bytes();
    let peer_id_hash = Sha256::digest(peer_id_bytes);

    // 验证签名
    root_public_key.verify(
        rsa::Pkcs1v15Sign::new_unprefixed(),
        &peer_id_hash,
        signature
    ).map_err(|_| CryptoError::VerifyFailed)?;

    Ok(())
}

/// 生成Peer ID和对应的密钥对
pub fn generate_peer_id() -> (Keypair, PeerId) {
    // 生成Ed25519密钥对
    let keypair = Keypair::generate_ed25519();
    let peer_id = keypair.public().to_peer_id();
    
    (keypair, peer_id)
}